import logging
import os
import sys
from io import BytesIO
from ipaddress import IPv4Address
from multiprocessing import Event
from typing import Any, Dict, List
from unittest.mock import MagicMock
from uuid import UUID

script_path = os.path.realpath(os.path.dirname(__file__))
monkey_path = os.path.realpath(os.path.join(script_path, "..", ".."))
sys.path.insert(0, monkey_path)

# Change this import to use this script with different plugins
from agent_plugins.exploiters.wmi.src.plugin import Plugin  # noqa: E402

from common import OperatingSystem  # noqa: E402
from common.credentials import Credentials, Password, Username  # noqa: E402
from common.event_queue import IAgentEventPublisher  # noqa: E402
from infection_monkey.exploit import IAgentBinaryRepository, IAgentOTPProvider  # noqa: E402
from infection_monkey.i_puppet import TargetHost  # noqa: E402
from infection_monkey.network import TCPPortSelector  # noqa: E402
from infection_monkey.propagation_credentials_repository import (  # noqa: E402
    IPropagationCredentialsRepository,
)

logging.basicConfig(level=logging.DEBUG)

# Modify these variables as needed
CREDENTIALS: List[Credentials] = [
    Credentials(identity=Username(username="m0nk3y"), secret=Password(password="Ivrrw5zEzs"))
]
EXPLOITER_OPTIONS: Dict[str, Any] = {}
TARGET_HOST = TargetHost(
    ip=IPv4Address("10.2.2.14"), operating_system=OperatingSystem.LINUX, icmp=True
)

agent_binary_repository = MagicMock(spec=IAgentBinaryRepository)
agent_binary_repository.get_agent_binary.return_value = BytesIO(b"M0nk3y was here")
agent_event_publisher = MagicMock(spec=IAgentEventPublisher)
agent_otp_provider = MagicMock(spec=IAgentOTPProvider)
agent_otp_provider.get_otp.return_value = "123456"
propagation_credentials_repository = MagicMock(spec=IPropagationCredentialsRepository)
propagation_credentials_repository.get_credentials.return_value = CREDENTIALS
tcp_port_selector = MagicMock(spec=TCPPortSelector)
tcp_port_selector.get_free_tcp_port.return_value = 12345

# These parameters don't matter because we won't be executing the agent
servers = ["localhost"]
current_depth = -1
interrupt = Event()
agent_id = UUID("67460e74-02e3-11e8-b443-00163e990bdb")

plugin = Plugin(
    plugin_name="Test",
    agent_id=agent_id,
    agent_event_publisher=agent_event_publisher,
    agent_binary_repository=agent_binary_repository,
    propagation_credentials_repository=propagation_credentials_repository,
    tcp_port_selector=tcp_port_selector,
    otp_provider=agent_otp_provider,
)

exploiter_result = plugin.run(
    host=TARGET_HOST,
    servers=servers,
    current_depth=current_depth,
    options=EXPLOITER_OPTIONS,
    interrupt=interrupt,
)

print(exploiter_result)
